using System.Windows.Forms;
using OhioState.AssetManaged;
using OhioState.Graphics;

namespace OhioState.Controls
{
    public partial class MatrixDisplay : UserControl
    {
        #region Constructors
        /// <summary>
        /// Default constructor.
        /// </summary>
        public MatrixDisplay() : this(true) { }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="displayModelViewMatrix">Boolean indicating whether the
        /// model-view matrix (true) or the projection matrix (false) is displayed.
        /// </param>
        public MatrixDisplay( bool displayModelViewMatrix )
        {
            this.displayModelViewMatrix = displayModelViewMatrix;
            InitializeComponent();
            initTextBoxes();
        }
        #endregion

        #region Public properties
        /// <summary>
        /// Get or set the camera that the display is attached to.
        /// </summary>
        public Camera CurrentCamera
        {
            
            get { return currentCamera; }
            set
            {
                SwapCamera(value);
            }
        }
        /// <summary>
        /// Get or set whether the model-view matrix (true) or the
        /// projection matrix (false) should be displayed.
        /// </summary>
        public bool DisplayModelViewMatrix
        {
            get { return displayModelViewMatrix; }
            set { displayModelViewMatrix = value; }
        }
        /// <summary>
        /// Get or set the format string used to display the numerical values
        /// in each text box. The default is "F2".
        /// </summary>
        public string FormatString
        {
            get { return formatString; }
            set { formatString = value; }
        }
        #endregion

        #region Private or protected methods
        private void SwapCamera( Camera value )
        {
            if (currentCamera == value)
                return;
            if (currentCamera != null)
            {
                DettachCamera(currentCamera);
            }
            if (value != null)
            {
                AttachCamera(value);
            }
        }

        private void AttachCamera( Camera value )
        {
            currentCamera = value;
            currentCamera.AddChangedEventHandler(currentCamera_Changed);
            currentCamera.AddChangingEventHandler(currentCamera_Changed);
        }

        private void DettachCamera( Camera currentCamera )
        {
            currentCamera.RemoveChangedEventHandler(currentCamera_Changed);
            currentCamera.RemoveChangingEventHandler(currentCamera_Changed);
        }

        private void currentCamera_Changed(IAssetManaged camera)
        {
            float[] values;
            if (displayModelViewMatrix)
            {
                values = currentCamera.GetModelViewMatrix().GetStreamRowOrder();
            }
            else
            {
                values = currentCamera.GetProjectionMatrix().GetStreamRowOrder();
            }
            int index = 0;
            this.SuspendLayout();
            foreach (TextBox control in textBoxes)
            {
                control.Text = values[index++].ToString(formatString);
            }
            this.ResumeLayout();
            this.PerformLayout();
        }
        private void initTextBoxes()
        {
            int index = 0;
            textBoxes[index++] = this.textBox00;
            textBoxes[index++] = this.textBox01;
            textBoxes[index++] = this.textBox02;
            textBoxes[index++] = this.textBox03;
            textBoxes[index++] = this.textBox10;
            textBoxes[index++] = this.textBox11;
            textBoxes[index++] = this.textBox12;
            textBoxes[index++] = this.textBox13;
            textBoxes[index++] = this.textBox20;
            textBoxes[index++] = this.textBox21;
            textBoxes[index++] = this.textBox22;
            textBoxes[index++] = this.textBox23;
            textBoxes[index++] = this.textBox30;
            textBoxes[index++] = this.textBox31;
            textBoxes[index++] = this.textBox32;
            textBoxes[index++] = this.textBox33;
        }
        #endregion

        #region Private fields
        private Camera currentCamera;
        private bool displayModelViewMatrix = true;
        private System.Windows.Forms.TextBox[] textBoxes = new TextBox[16];
        private string formatString = "F2";
        #endregion
    }
}
